#
# Deepant Anonymous Instant Chat
#
# Copyright (c) 2011, http://deepant.com
#
# This free software is licensed under the GPL License, Version 3, 29 June 2007 (the "License").
# To obtain a copy of the licence, visit : http://www.gnu.org/copyleft/gpl.html
#
# This software is distributed WITHOUT ANY WARRANTY OR CONDITION OF ANY KIND.
# Please see the license for more information.
#
#  

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
import wsgiref.handlers
import logging
from chatserver_deepant import UserCollection,DeepantHandler;
from os import path;
    
class UserCollectionStore(db.Model):
    modelName = "UserCollectionStore"
    title = db.StringProperty()
    data = db.BlobProperty(default=None)
    version= db.IntegerProperty()

    @staticmethod
    def getUserCollectionStore(title):
        results = db.GqlQuery("SELECT * FROM " + UserCollectionStore.modelName + " WHERE title = :1", title).fetch(1000)
        #Data inconsisitence happen
        #Remove all except one left
        Log("size:" + str(len(results)));
        if (len(results) < 1):
            return None;
        if (len(results) > 1):
            removeList = list();
            for i in range(1, len(results)):
                removeList.append(results[i].key());
            db.delete(removeList);
            Log("size2:" + str(len(results)));
        return results[0];
        
    @staticmethod
    def saveUserCollectionStore(title, data, version):
        existedObject = UserCollectionStore.getUserCollectionStore(title);
        if (existedObject != None):
            data = UserCollection.marshal();
            existedObject.data = db.Blob(data)
            existedObject.version = version
            existedObject.put()
        else:
            store = UserCollectionStore()
            data = UserCollection.marshal();
            store.title = title;
            store.data = db.Blob(data)
            store.version = version
            store.put() 
    
def Log(msg):
    logging.info(msg);
    
#As Appengine will not always keep the app in the memory
#We need to serialize/deserialize it  using datastore API
class UserCollectionAppEngine(UserCollection):
    @staticmethod
    def onLoad():
        if (UserCollection.notCreatedYet()):
            storeData = None
            store = UserCollectionStore.getUserCollectionStore("usercollection");
            
            if (store):
                storeData = store.data;
            if (storeData != None):
                UserCollection.unMarshal(storeData);
                #Log("Load from DB" +    UserCollection.getInstance().printAll()); 
            return  UserCollection.getInstance()   
        else:
            store = UserCollectionStore.getUserCollectionStore("usercollection");
            if (store and store.version and store.version != UserCollection.getInstance().version()):
                storeData = store.data;
                if (storeData != None):
                    UserCollection.unMarshal(storeData);
                    #Log("Load from DB" +    UserCollection.getInstance().printAll()); 
    
    @staticmethod
    def onFinish():    
        if (UserCollection.getInstance().contentChanged()):
            #marshal into datastore
            oldVersion = UserCollection.getInstance().version()
            UserCollection.getInstance().setVersion(oldVersion + 1);
            data = UserCollection.marshal();
            #Log("Save to DB" +    UserCollection.getInstance().printAll());
            UserCollectionStore.saveUserCollectionStore("usercollection", data, oldVersion + 1);
            UserCollection.getInstance().notifyContentChanged(False);
        
class AppEngineHandler(DeepantHandler, webapp.RequestHandler):
    def get(self):
        DeepantHandler.handlerGet(self);
    
    def post(self):
        DeepantHandler.handlerPost(self);

    def writeBody(self, data):
        self.response.out.write(data);
    
    def writeHeader(self, name, value):
        if (self.response.headers[name] != None):
            self.response.headers[name] = value;
        else:
            self.response.headers.add_header(name, value)
            
        #Log(self.response.headers[name])
        
    def endWriteHeader(self):
        pass;

    def getQuery(self):
        return self.request.query_string;
        
    def getRealPath(self):
        return self.request.path;

    def getRequestHeader(self, name):
        return self.request.headers[name]
    
    def getRequestBody(self):
        return self.request.body
        
    def Log(self, msg):
        Log(msg);
        pass;
        
    def writeResponseStatus(self, status):
        self.response.set_status(status) 
    
    def onStart(self):
        UserCollectionAppEngine.onLoad();
        
    def onFinish(self):
        UserCollectionAppEngine.onFinish();

    def serveStaticFile(self):

        try:
            self.Log(path.dirname(__file__) + path.sep + "static"  + self.getRealPath());
            f = open(path.dirname(__file__) + path.sep + "static"  + self.getRealPath(), 'rb');
        except:
            return;       
            
        self.writeResponseStatus(200)
        body = f.read();
        if (self.getRealPath().endswith(".ogg")):
            self.writeHeader('Content-Type', 'video/ogg')
            self.writeHeader('max-age', '31536000')
            self.writeHeader('Expires', "Fri, 01-Jan-2099 00:00:00 GMT")
            self.writeHeader('Cache-Control', "max-age=311040000")
            self.writeHeader('Accept-Ranges', 'bytes')
            self.writeHeader('Content-Length', str(len(body)))
            self.writeHeader('Content-Range', "bytes 0-" + str(len(body) - 1) + "/" + str(len(body)))
        elif (self.getRealPath().endswith(".mp3")):
            self.writeHeader('Content-Type', 'audio/mpeg')
            self.writeHeader('Accept-Ranges', 'bytes')
            self.writeHeader('max-age', '31536000')
            self.writeHeader('Cache-Control', "max-age=311040000")
            self.writeHeader('Expires', "Fri, 01-Jan-2099 00:00:00 GMT")
            self.writeHeader('Content-Length', str(len(body)))
            self.writeHeader('Content-Range', "bytes 0-" + str(len(body) - 1) + "/" + str(len(body)))
        else:
            self.writeHeader('Content-Type', 'text/html; charset=UTF-8')
        self.endWriteHeader()
        self.writeBody(body)
        f.close()
        return 
        
  
        
application = webapp.WSGIApplication([(r'.*', AppEngineHandler)],debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()